home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / HENSA / MATHS / PLPLOT / PLPLOT.ZIP / src / pdfutils.c next >
Encoding:
C/C++ Source or Header  |  1994-08-25  |  18.9 KB  |  793 lines

  1. /* $Id: pdfutils.c,v 1.11 1994/08/25 04:04:06 mjl Exp $
  2.  * $Log: pdfutils.c,v $
  3.  * Revision 1.11  1994/08/25  04:04:06  mjl
  4.  * Eliminated an unnecessary header file inclusion.
  5.  *
  6.  * Revision 1.10  1994/06/30  18:21:56  mjl
  7.  * All core source files: made another pass to eliminate warnings when using
  8.  * gcc -Wall.  Lots of cleaning up: got rid of includes of math.h or string.h
  9.  * (now included by plplot.h), and other minor changes.  Now each file has
  10.  * global access to the plstream pointer via extern; many accessor functions
  11.  * eliminated as a result.
  12. */
  13.  
  14. /*--------------------------------------------------------------------------*\
  15.  
  16.     pdf_utils.c
  17.  
  18.     Copyright (C) 1992 by Maurice J. LeBrun
  19.  
  20.     This software may be freely copied, modified and redistributed without
  21.     fee provided that this copyright notice is preserved intact on all
  22.     copies and modified copies.
  23.  
  24.     There is no warranty or other guarantee of fitness of this software.
  25.     It is provided solely "as is". The author(s) disclaim(s) all
  26.     responsibility and liability with respect to this software's usage or
  27.     its effect upon hardware or computer systems.
  28.  
  29. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  30.  
  31.     These functions do the low-level reading/writing of portable data files.
  32.     Data can be written to/read from either a file handle or memory buffer.
  33. \*--------------------------------------------------------------------------*/
  34.  
  35. #include "plplotP.h"
  36.  
  37. static void print_ieeef    (void *, void *);
  38. static int  pdf_wrx    (const U_CHAR *x, long nitems, PDFstrm *pdfs);
  39. static int  pdf_rdx    (U_CHAR *x, long nitems, PDFstrm *pdfs);
  40.  
  41. static int debug = 0;
  42.  
  43. /*--------------------------------------------------------------------------*\
  44.  * void pdf_set (string, value)
  45.  *
  46.  * Set an option.  Pretty sparse right now but you never know.
  47. \*--------------------------------------------------------------------------*/
  48.  
  49. void
  50. pdf_set(char *option, int value)
  51. {
  52.     if ( ! strcmp(option, "debug"))
  53.     debug = value;
  54. }
  55.  
  56. /*----------------------------------------------------------------------*\
  57.  * pdf_fopen()
  58.  *
  59.  * Initializes a PDFstrm for a file oriented device.
  60.  * Used exactly like fopen().
  61. \*----------------------------------------------------------------------*/
  62.  
  63. PDFstrm *
  64. pdf_fopen(char *filename, char *mode)
  65. {
  66.     PDFstrm *pdfs;
  67.  
  68.     dbug_enter("pdf_fopen");
  69.  
  70.     pdfs = (PDFstrm *) malloc(sizeof(PDFstrm));
  71.  
  72.     if (pdfs != NULL) {
  73.     pdfs->buffer = NULL;
  74.  
  75.     pdfs->file = fopen(filename, mode);
  76.     if (pdfs->file == NULL) {
  77.         pdf_close(pdfs);
  78.         pdfs = NULL;
  79.     }
  80.     }
  81.  
  82.     return pdfs;
  83. }
  84.  
  85. /*----------------------------------------------------------------------*\
  86.  * pdf_bopen()
  87.  *
  88.  * Initializes a PDFstrm for reading/writing to a memory buffer.
  89.  * If buffer is NULL, a standard buffer is allocated.
  90. \*----------------------------------------------------------------------*/
  91.  
  92. PDFstrm *
  93. pdf_bopen(U_CHAR *buffer, long bufmax)
  94. {
  95.     PDFstrm *pdfs;
  96.  
  97.     dbug_enter("pdf_bopen");
  98.  
  99.     pdfs = (PDFstrm *) malloc(sizeof(PDFstrm));
  100.  
  101.     if (pdfs != NULL) {
  102.     pdfs->file = NULL;
  103.     pdfs->bp = 0;
  104.  
  105.     if (buffer == NULL) {
  106.         if (bufmax > 0)
  107.         pdfs->bufmax = bufmax;
  108.         else
  109.         pdfs->bufmax = 2048;
  110.  
  111.         pdfs->buffer = (U_CHAR *) malloc(pdfs->bufmax);
  112.         if (pdfs->buffer == NULL) {
  113.         pdf_close(pdfs);
  114.         pdfs = NULL;
  115.         }
  116.     }
  117.     else {
  118.         pdfs->bufmax = bufmax;
  119.         pdfs->buffer = buffer;
  120.     }
  121.     }
  122.  
  123.     return pdfs;
  124. }
  125.  
  126. /*----------------------------------------------------------------------*\
  127.  * pdf_finit()
  128.  *
  129.  * Initializes a PDFstrm for a file oriented device.
  130.  * Like pdf_fopen() but an existing file handle is specified.
  131. \*----------------------------------------------------------------------*/
  132.  
  133. PDFstrm *
  134. pdf_finit(FILE *file)
  135. {
  136.     PDFstrm *pdfs;
  137.  
  138.     dbug_enter("pdf_finit");
  139.  
  140.     pdfs = (PDFstrm *) malloc(sizeof(PDFstrm));
  141.  
  142.     if (pdfs != NULL) {
  143.     pdfs->buffer = NULL;
  144.     pdfs->file = file;
  145.     }
  146.  
  147.     return pdfs;
  148. }
  149.  
  150. /*----------------------------------------------------------------------*\
  151.  * pdf_close()
  152.  *
  153.  * Closes a PDFstrm.
  154.  * Used exactly like fclose().
  155. \*----------------------------------------------------------------------*/
  156.  
  157. int
  158. pdf_close(PDFstrm *pdfs)
  159. {
  160.     dbug_enter("pdf_close");
  161.  
  162.     if (pdfs != NULL) {
  163.     if (pdfs->file != NULL)
  164.         fclose(pdfs->file);
  165.  
  166.     else if (pdfs->buffer != NULL)
  167.         free ((void *) pdfs->buffer);
  168.  
  169.     free((void *) pdfs);
  170.     }
  171.     return 0;
  172. }
  173.  
  174. /*----------------------------------------------------------------------*\
  175.  * int pdf_putc()
  176.  *
  177.  * Writes a single character.
  178. \*----------------------------------------------------------------------*/
  179.  
  180. int
  181. pdf_putc(int c, PDFstrm *pdfs)
  182. {
  183.     int result = EOF;
  184.  
  185.     if (pdfs->file != NULL) {
  186.     result = putc(c, pdfs->file);
  187.     pdfs->bp++;
  188.     }
  189.     else if (pdfs->buffer != NULL) {
  190.     if (pdfs->bp >= pdfs->bufmax) {
  191.         pdfs->bufmax += 512;
  192. #ifdef DEBUG
  193.         fprintf(stderr,
  194.             "pdf_putc: Increasing buffer to %d bytes\n",
  195.             pdfs->bufmax);
  196. #endif            
  197.         pdfs->buffer = (U_CHAR *)
  198.         realloc((void *) pdfs->buffer, pdfs->bufmax);
  199.     }
  200.     pdfs->buffer[pdfs->bp++] = c;
  201.     result = c;
  202.     }
  203.     else
  204.     plexit("pdf_putc: Illegal operation");
  205.  
  206.     return result;
  207. }
  208.  
  209. /*----------------------------------------------------------------------*\
  210.  * int pdf_getc()
  211.  *
  212.  * Reads a single character.
  213. \*----------------------------------------------------------------------*/
  214.  
  215. int
  216. pdf_getc(PDFstrm *pdfs)
  217. {
  218.     int result = EOF;
  219.  
  220.     if (pdfs->file != NULL) {
  221.     result = getc(pdfs->file);
  222.     pdfs->bp++;
  223.     }
  224.     else if (pdfs->buffer != NULL) {
  225.     if (pdfs->bp < pdfs->bufmax)
  226.         result = pdfs->buffer[pdfs->bp++];
  227.     }
  228.     else
  229.     plexit("pdf_getc: Illegal operation");
  230.  
  231.     return result;
  232. }
  233.  
  234. /*----------------------------------------------------------------------*\
  235.  * int pdf_ungetc()
  236.  *
  237.  * Push back the last command read.
  238. \*----------------------------------------------------------------------*/
  239.  
  240. int
  241. pdf_ungetc(int c, PDFstrm *pdfs)
  242. {
  243.     int result = EOF;
  244.  
  245.     if (pdfs->file != NULL) {
  246.     result = ungetc(c, pdfs->file);
  247.     if (pdfs->bp > 0) 
  248.         pdfs->bp--;
  249.     }
  250.     else if (pdfs->buffer != NULL) {
  251.     if (pdfs->bp > 0) {
  252.         pdfs->buffer[--pdfs->bp] = c;
  253.         result = c;
  254.     }
  255.     }
  256.     else
  257.     plexit("pdf_ungetc: Illegal operation");
  258.  
  259.     return result;
  260. }
  261.  
  262. /*----------------------------------------------------------------------*\
  263.  * int pdf_wrx()
  264.  *
  265.  * Writes a record.
  266. \*----------------------------------------------------------------------*/
  267.  
  268. static int
  269. pdf_wrx(const U_CHAR *x, long nitems, PDFstrm *pdfs)
  270. {
  271.     int i, result = 0;
  272.  
  273.     if (pdfs->file != NULL) {
  274.     result = fwrite(x, 1, nitems, pdfs->file);
  275.     pdfs->bp += nitems;
  276.     }
  277.     else if (pdfs->buffer != NULL) {
  278.     for (i = 0; i < nitems; i++) {
  279.         if (pdfs->bp >= pdfs->bufmax) {
  280.         pdfs->bufmax += 512;
  281. #ifdef DEBUG
  282.         fprintf(stderr,
  283.             "pdf_wrx: Increasing buffer to %d bytes\n",
  284.             pdfs->bufmax);
  285. #endif            
  286.         pdfs->buffer = (U_CHAR *)
  287.             realloc((void *) (pdfs->buffer), pdfs->bufmax);
  288.         }
  289.         pdfs->buffer[pdfs->bp++] = x[i];
  290.     }
  291.     result = i;
  292.     }
  293.  
  294.     return result;
  295. }
  296.  
  297. /*----------------------------------------------------------------------*\
  298.  * int pdf_rdx()
  299.  *
  300.  * Reads a record.
  301. \*----------------------------------------------------------------------*/
  302.  
  303. static int
  304. pdf_rdx(U_CHAR *x, long nitems, PDFstrm *pdfs)
  305. {
  306.     int i, result = 0;
  307.  
  308.     if (pdfs->file != NULL) {
  309.     result = fread(x, 1, nitems, pdfs->file);
  310.     pdfs->bp += nitems;
  311.     }
  312.     else if (pdfs->buffer != NULL) {
  313.     for (i = 0; i < nitems; i++) {
  314.         if (pdfs->bp > pdfs->bufmax)
  315.         break;
  316.         x[i] = pdfs->buffer[pdfs->bp++];
  317.     }
  318.     result = i;
  319.     }
  320.  
  321.     return result;
  322. }
  323.  
  324. /*----------------------------------------------------------------------*\
  325.  * pdf_wr_header()
  326.  *
  327.  * Writes a header string.  Input string must be NULL-terminated.  The
  328.  * written string is terminated by a new-line, not a NULL.  This is done
  329.  * so you can type e.g. "% strings <file> | head" and get sensible output.
  330. \*----------------------------------------------------------------------*/
  331.  
  332. int
  333. pdf_wr_header(PDFstrm *pdfs, char *header)
  334. {
  335.     int i;
  336.  
  337.     dbug_enter("pdf_wr_header");
  338.  
  339.     for (i = 0; i < 79; i++) {
  340.     if (header[i] == '\0')
  341.         break;
  342.     if (pdf_putc(header[i], pdfs) == EOF)
  343.         return PDF_WRERR;
  344.     }
  345.     if (pdf_putc('\n', pdfs) == EOF)
  346.     return PDF_WRERR;
  347.  
  348.     return 0;
  349. }
  350.  
  351. /*----------------------------------------------------------------------*\
  352.  * int pdf_rd_header
  353.  *
  354.  * Reads a newline-terminated header string from PDFstrm *pdfs, and
  355.  * converts to a usual NULL-terminated string.  80 chars maximum assumed.
  356. \*----------------------------------------------------------------------*/
  357.  
  358. int
  359. pdf_rd_header(PDFstrm *pdfs, char *header)
  360. {
  361.     int i;
  362.  
  363.     dbug_enter("pdf_rd_header");
  364.  
  365.     for (i = 0; i < 79; i++) {
  366.     if ((header[i] = pdf_getc(pdfs)) == EOF)
  367.         return PDF_RDERR;
  368.  
  369.     if (header[i] == '\n')
  370.         break;
  371.     }
  372.     header[i] = '\0';        /* NULL terminate */
  373.     return 0;
  374. }
  375.  
  376. /*----------------------------------------------------------------------*\
  377.  * int pdf_wr_1byte()
  378.  *
  379.  * Writes a U_CHAR as a single byte.
  380. \*----------------------------------------------------------------------*/
  381.  
  382. int
  383. pdf_wr_1byte(PDFstrm *pdfs, U_CHAR s)
  384. {
  385.     U_CHAR x[1];
  386.  
  387.     x[0] = s;
  388.     if (pdf_wrx(x, 1, pdfs) != 1)
  389.     return PDF_WRERR;
  390.  
  391.     return 0;
  392. }
  393.  
  394. /*----------------------------------------------------------------------*\
  395.  * int pdf_rd_1byte()
  396.  *
  397.  * Reads a single byte, storing into a U_CHAR.
  398. \*----------------------------------------------------------------------*/
  399.  
  400. int
  401. pdf_rd_1byte(PDFstrm *pdfs, U_CHAR *ps)
  402. {
  403.     U_CHAR x[1];
  404.  
  405.     if ( ! pdf_rdx(x, 1, pdfs))
  406.     return PDF_RDERR;
  407.  
  408.     *ps = ((U_CHAR) x[0]);
  409.     return 0;
  410. }
  411.  
  412. /*----------------------------------------------------------------------*\
  413.  * pdf_wr_2bytes()
  414.  *
  415.  * Writes a U_SHORT as two single bytes, low end first.
  416. \*----------------------------------------------------------------------*/
  417.  
  418. int
  419. pdf_wr_2bytes(PDFstrm *pdfs, U_SHORT s)
  420. {
  421.     U_CHAR x[2];
  422.  
  423.     x[0] = (U_CHAR) ((U_LONG) (s & (U_LONG) 0x00FF));
  424.     x[1] = (U_CHAR) ((U_LONG) (s & (U_LONG) 0xFF00) >> 8);
  425.  
  426.     if (pdf_wrx(x, 2, pdfs) != 2)
  427.     return PDF_WRERR;
  428.  
  429.     return 0;
  430. }
  431.  
  432. /*----------------------------------------------------------------------*\
  433.  * pdf_rd_2bytes()
  434.  *
  435.  * Reads a U_SHORT from two single bytes, low end first.
  436. \*----------------------------------------------------------------------*/
  437.  
  438. int
  439. pdf_rd_2bytes(PDFstrm *pdfs, U_SHORT *ps)
  440. {
  441.     U_CHAR x[2];
  442.  
  443.     if ( ! pdf_rdx(x, 2, pdfs))
  444.     return PDF_RDERR;
  445.  
  446.     *ps = 0;
  447.     *ps |= (U_LONG) x[0];
  448.     *ps |= (U_LONG) x[1] << 8;
  449.  
  450.     return 0;
  451. }
  452.  
  453. /*----------------------------------------------------------------------*\
  454.  * pdf_wr_2nbytes()
  455.  *
  456.  * Writes n U_SHORT's as 2n single bytes, low end first.
  457. \*----------------------------------------------------------------------*/
  458.  
  459. int
  460. pdf_wr_2nbytes(PDFstrm *pdfs, U_SHORT *s, PLINT n)
  461. {
  462.     PLINT i;
  463.     U_CHAR x[2];
  464.  
  465.     for (i = 0; i < n; i++) {
  466.     x[0] = (U_CHAR) ((U_LONG) (s[i] & (U_LONG) 0x00FF));
  467.     x[1] = (U_CHAR) ((U_LONG) (s[i] & (U_LONG) 0xFF00) >> 8);
  468.  
  469.     if (pdf_wrx(x, 2, pdfs) != 2)
  470.         return PDF_WRERR;
  471.     }
  472.     return 0;
  473. }
  474.  
  475. /*----------------------------------------------------------------------*\
  476.  * pdf_rd_2nbytes()
  477.  *
  478.  * Reads n U_SHORT's from 2n single bytes, low end first.
  479. \*----------------------------------------------------------------------*/
  480.  
  481. int
  482. pdf_rd_2nbytes(PDFstrm *pdfs, U_SHORT *s, PLINT n)
  483. {
  484.     PLINT i;
  485.     U_CHAR x[2];
  486.  
  487.     for (i = 0; i < n; i++) {
  488.     if ( ! pdf_rdx(x, 2, pdfs))
  489.         return PDF_RDERR;
  490.  
  491.     s[i] = 0;
  492.     s[i] |= (U_SHORT) x[0];
  493.     s[i] |= (U_SHORT) x[1] << 8;
  494.     }
  495.     return 0;
  496. }
  497.  
  498. /*----------------------------------------------------------------------*\
  499.  * pdf_wr_4bytes()
  500.  *
  501.  * Writes an unsigned long as four single bytes, low end first.
  502. \*----------------------------------------------------------------------*/
  503.  
  504. int
  505. pdf_wr_4bytes(PDFstrm *pdfs, U_LONG s)
  506. {
  507.     U_CHAR x[4];
  508.  
  509.     x[0] = (U_CHAR) ((s & (U_LONG) 0x000000FF));
  510.     x[1] = (U_CHAR) ((s & (U_LONG) 0x0000FF00) >> 8);
  511.     x[2] = (U_CHAR) ((s & (U_LONG) 0x00FF0000) >> 16);
  512.     x[3] = (U_CHAR) ((s & (U_LONG) 0xFF000000) >> 24);
  513.  
  514.     if (pdf_wrx(x, 4, pdfs) != 4)
  515.     return PDF_WRERR;
  516.  
  517.     return 0;
  518. }
  519.  
  520. /*----------------------------------------------------------------------*\
  521.  * pdf_rd_4bytes()
  522.  *
  523.  * Reads an unsigned long from 4 single bytes, low end first.
  524. \*----------------------------------------------------------------------*/
  525.  
  526. int
  527. pdf_rd_4bytes(PDFstrm *pdfs, U_LONG *ps)
  528. {
  529.     U_CHAR x[4];
  530.  
  531.     if ( ! pdf_rdx(x, 4, pdfs))
  532.     return PDF_RDERR;
  533.  
  534.     *ps = 0;
  535.     *ps |= (U_LONG) x[0];
  536.     *ps |= (U_LONG) x[1] << 8;
  537.     *ps |= (U_LONG) x[2] << 16;
  538.     *ps |= (U_LONG) x[3] << 24;
  539.  
  540.     return 0;
  541. }
  542.  
  543. /*----------------------------------------------------------------------*\
  544.  * Here is the IEEE floating point specification in both 32 bit and 64 bit
  545.  * precisions, from page 9 of "IEEE Standard for Binary Floating-Point
  546.  * Arithmetic", copyright 1985, IEEE Std 754-1985:
  547.  * 
  548.  * 
  549.  *                             Single Format
  550.  * 
  551.  * msb means most significant bit
  552.  * lsb means least significant bit
  553.  * 
  554.  *   1         8                                23
  555.  * _____________________________________________________________________
  556.  * |   |                |                                              |
  557.  * | s |       e        |                        f                     |
  558.  * |___|________________|______________________________________________|
  559.  *      msb          lsb msb                                        lsb
  560.  * 
  561.  * 
  562.  * 
  563.  *                             Double Format
  564.  * 
  565.  * msb means most significant bit
  566.  * lsb means least significant bit
  567.  * 
  568.  *   1        11                                52
  569.  * _____________________________________________________________________
  570.  * |   |                |                                              |
  571.  * | s |       e        |                        f                     |
  572.  * |___|________________|______________________________________________|
  573.  *      msb          lsb msb                                        lsb
  574.  * 
  575.  * 
  576.  * (Thanks to: Andy Mai (mai@ncar.ucar.edu))
  577.  * 
  578.  * 
  579.  * According to "inmos: Transputer instruction set" the IEEE standard
  580.  * specifies the floating format as:
  581.  * 
  582.  *      s exp frac
  583.  * 
  584.  * Where: s = sign bit  (1 bit)
  585.  *      exp = exponent (8 bits for 32 bit float / 11 bits for 64 bit float)
  586.  *      frac = fraction (23 bits for 32 bit float / 52 bits for 64 bit float)
  587.  * 
  588.  * value of (s exp frac) = (-1)^s * 1.frac * 2^(exp-bias) ; if exp not 0
  589.  *                         (-1)^s * 0.frac * 2^(1-bias) ; if exp = 0
  590.  * 
  591.  * where bias = 127 for 32 bit float
  592.  *       bias = 1023 for 64 bit float
  593.  * 
  594.  * (Thanks to: Tom Bjorkholm(TBJORKHOLM@abo.fi))
  595.  * 
  596. \*----------------------------------------------------------------------*/
  597.  
  598. /*----------------------------------------------------------------------*\
  599.  * int pdf_wr_ieeef()
  600.  *
  601.  * Writes a float in IEEE single precision (32 bit) format.
  602. \*----------------------------------------------------------------------*/
  603.  
  604. int
  605. pdf_wr_ieeef(PDFstrm *pdfs, float f)
  606. {
  607.     double fdbl, fmant, f_new;
  608.     float fsgl, f_tmp;
  609.     int istat, exp, e_new, e_off, bias = 127;
  610.     U_LONG value, s_ieee, e_ieee, f_ieee;
  611.  
  612.     if (f == 0.0) {
  613.     value = 0;
  614.     return (pdf_wr_4bytes(pdfs, value));
  615.     }
  616.     fsgl = fdbl = f;
  617.     fmant = frexp(fdbl, &exp);
  618.  
  619.     if (fmant < 0)
  620.     s_ieee = 1;
  621.     else
  622.     s_ieee = 0;
  623.  
  624.     fmant = fabs(fmant);
  625.     f_new = 2 * fmant;
  626.     e_new = exp - 1;
  627.  
  628.     if (e_new < 1 - bias) {
  629.     e_off = e_new - (1 - bias);
  630.     e_ieee = 0;
  631.     f_tmp = f_new * pow((double) 2.0, (double) e_off);
  632.     }
  633.     else {
  634.     e_ieee = e_new + bias;
  635.     f_tmp = f_new - 1;
  636.     }
  637.     f_ieee = f_tmp * 8388608;        /* multiply by 2^23 */
  638.  
  639.     if (e_ieee > 255) {
  640.     if (debug)
  641.         fprintf(stderr, "pdf_wr_ieeef: Warning -- overflow\n");
  642.     e_ieee = 255;
  643.     }
  644.  
  645.     s_ieee = s_ieee << 31;
  646.     e_ieee = e_ieee << 23;
  647.  
  648.     value = s_ieee | e_ieee | f_ieee;
  649.  
  650.     if ((istat = pdf_wr_4bytes(pdfs, value)))
  651.     return (istat);
  652.  
  653.     if (debug) {
  654.     fprintf(stderr, "Float value (written):      %g\n", fsgl);
  655.     print_ieeef(&fsgl, &value);
  656.     }
  657.  
  658.     return 0;
  659. }
  660.  
  661. /*----------------------------------------------------------------------*\
  662.  * int pdf_rd_ieeef()
  663.  *
  664.  * Reads a float from a IEEE single precision (32 bit) format.
  665. \*----------------------------------------------------------------------*/
  666.  
  667. int
  668. pdf_rd_ieeef(PDFstrm *pdfs, float *pf)
  669. {
  670.     double f_new, f_tmp;
  671.     float fsgl;
  672.     int istat, exp, bias = 127;
  673.     U_LONG value, s_ieee, e_ieee, f_ieee;
  674.  
  675.     if ((istat = pdf_rd_4bytes(pdfs, &value)))
  676.     return (istat);
  677.  
  678.     s_ieee = (value & (U_LONG) 0x80000000) >> 31;
  679.     e_ieee = (value & (U_LONG) 0x7F800000) >> 23;
  680.     f_ieee = (value & (U_LONG) 0x007FFFFF);
  681.  
  682.     f_tmp = (double) f_ieee / 8388608.0;    /* divide by 2^23 */
  683.  
  684.     if (e_ieee == 0) {
  685.     exp = 1 - bias;
  686.     f_new = f_tmp;
  687.     }
  688.     else {
  689.     exp = (int) e_ieee - bias;
  690.     f_new = 1.0 + f_tmp;
  691.     }
  692.  
  693.     fsgl = f_new * pow(2.0, (double) exp);
  694.     if (s_ieee == 1)
  695.     fsgl = -fsgl;
  696.  
  697.     *pf = fsgl;
  698.  
  699.     if (debug) {
  700.     fprintf(stderr, "Float value (read):      %g\n", fsgl);
  701.     print_ieeef(&fsgl, &value);
  702.     }
  703.  
  704.     return 0;
  705. }
  706.  
  707. /*----------------------------------------------------------------------*\
  708.  * print_ieeef()
  709.  *
  710.  * Prints binary representation for numbers pointed to by arguments.
  711.  * The first argument is the original float, the second is the
  712.  * IEEE representation.  They should be the same on any machine that
  713.  * uses IEEE floats.
  714. \*----------------------------------------------------------------------*/
  715.  
  716. static void
  717. print_ieeef(void *vx, void *vy)
  718. {
  719.     int i;
  720.     U_LONG f, *x = (U_LONG *) vx, *y = (U_LONG *) vy;
  721.     char bitrep[33];
  722.  
  723.     bitrep[32] = '\0';
  724.  
  725.     f = *x;
  726.     for (i = 0; i < 32; i++) {
  727.     if (f & 1)
  728.         bitrep[32 - i - 1] = '1';
  729.     else
  730.         bitrep[32 - i - 1] = '0';
  731.     f = f >> 1;
  732.     }
  733.     fprintf(stderr, "Binary representation:      ");
  734.     fprintf(stderr, "%s\n", bitrep);
  735.  
  736.     f = *y;
  737.     for (i = 0; i < 32; i++) {
  738.     if (f & 1)
  739.         bitrep[32 - i - 1] = '1';
  740.     else
  741.         bitrep[32 - i - 1] = '0';
  742.     f = f >> 1;
  743.     }
  744.     fprintf(stderr, "Converted representation:   ");
  745.     fprintf(stderr, "%s\n\n", bitrep);
  746.  
  747.     return;
  748. }
  749.  
  750. /*----------------------------------------------------------------------*\
  751.  * plAlloc2dGrid()
  752.  *
  753.  * Allocates a block of memory for use as a 2-d grid of PLFLT's.
  754.  * Resulting array can be indexed as f[i][j] anywhere.  This is to be used
  755.  * instead of PLFLT f[nx][ny], which is less useful.  Note that this type
  756.  * of allocation is required by the PLPLOT functions which take a 2-d
  757.  * grids of PLFLT's as an argument, such as plcont() and plot3d().
  758.  * Example usage:
  759.  *
  760.  *   PLFLT **z;
  761.  *
  762.  *   Alloc2dGrid(&z, XPTS, YPTS);
  763.  *
  764. \*----------------------------------------------------------------------*/
  765.  
  766. void
  767. plAlloc2dGrid(PLFLT ***f, PLINT nx, PLINT ny)
  768. {
  769.     PLINT i;
  770.  
  771.     *f = (PLFLT **) malloc(nx * sizeof(PLFLT *));
  772.     for (i = 0; i < nx; i++) {
  773.     (*f)[i] = (PLFLT *) malloc(ny * sizeof(PLFLT));
  774.     }
  775. }
  776.  
  777. /*----------------------------------------------------------------------*\
  778.  * Free2dGrid()
  779.  *
  780.  * Frees a block of memory allocated with Alloc2dGrid().
  781. \*----------------------------------------------------------------------*/
  782.  
  783. void
  784. plFree2dGrid(PLFLT **f, PLINT nx, PLINT ny)
  785. {
  786.     PLINT i;
  787.  
  788.     for (i = 0; i < nx; i++)
  789.     free((void *) f[i]);
  790.  
  791.     free((void *) f);
  792. }
  793.